package com.authcode.service;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.metadata.Sheet;
import com.authcode.domain.*;
import com.authcode.easyexcel.ExcelExportEntity;
import com.authcode.easyexcel.ExcelTemplateExportEntity;
import com.authcode.easyexcel.ExcelUtils;
import com.authcode.utils.FileUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述:
 *
 * @author jianweiwang
 * @version v1.0
 * @link wjw@choicesoft.com.cn
 * @date 2019/4/1 14:33
 **/
@Service
public class AuthExeService {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
    private String dateTime;

    private static volatile String filePath="";
    private static volatile String fileName="";


    public void execute(MultipartFile file, HttpServletResponse response, String demandName, String demandUser) throws IOException {
        String dateTime = formatter.format(LocalDateTime.now());
        this.dateTime = dateTime;
        String fileName = "01_中台_权限编码_" + demandName + "_测试_全部商户_" + dateTime + "_" + demandUser + ".sql";
//        File directory = new File("C:\\Users\\ThinkPad\\Desktop\\辰森供应链\\权限编码\\ttt-pre-pro\\ttt\\");
        File directory = new File("/var/log/authcode");
        File file1 = new File(directory, fileName);
        boolean newFile = false;
        if (directory.exists()) {
            newFile = file1.createNewFile();
        } else {
            boolean mkdirs = directory.mkdirs();
            if (mkdirs) {
                newFile = file1.createNewFile();
            }
        }
        if (newFile) {
            //获取model数据
            List<AuthExeModel> list = getAuthExeModels(file);
            //创建文件
            FileOutputStream os = new FileOutputStream(file1);
            String start = "set SESSION AUTOCOMMIT=0;"+"\r\n";
            os.write(start.getBytes());
            for (AuthExeModel model : list) {
                String code = model.getCode().trim();
                String parentCode = model.getParentCode().trim();
                String name = model.getModelName().trim();
                String originalCode = model.getOriginalCode();
                String originalParentCode = model.getOriginalParentCode();
                String originalModelName = model.getOriginalModelName();
                String menuId = UUID.randomUUID().toString().replaceAll("-", "").trim();
                Integer isDelete = model.getIsDelete();
                //创建sql语句
                generateSQL(os, code, parentCode, name, originalCode, originalParentCode, originalModelName, menuId, isDelete);
            }
            os.write("COMMIT;".getBytes());
            os.close();
            //重定向
            AuthExeService.filePath = file1.getAbsolutePath();
            AuthExeService.fileName = fileName;
            response.sendRedirect("/success");
        } else {
            throw new RuntimeException("权限脚本文件创建失败啦！请检查执行文档是否有错误。");
        }

    }


    private List<AuthExeModel> getAuthExeModels(MultipartFile file) throws IOException {
        InputStream inputStream = file.getInputStream();
        List<Object> dataList = EasyExcelFactory.read(inputStream, new Sheet(1, 1, AuthExeModel.class));
        inputStream.close();
        return dataList.stream().map(o -> {
            AuthExeModel model = new AuthExeModel();
            BeanUtils.copyProperties(o, model);
            return model;
        }).collect(Collectors.toList());
    }

    private void generateSQL(FileOutputStream os, String code, String parentCode, String name, String originalCode, String originalParentCode, String originalModelName, String menuId, Integer isDelete) throws IOException {
        required(code,parentCode,name);
        isDelete = Optional.ofNullable(isDelete).orElse(0);
        if (1 == Optional.of(isDelete).get()) {
            commonSql(os, code);
        } else {
            if (StringUtils.isEmpty(originalCode) && StringUtils.isEmpty(originalParentCode) && StringUtils.isEmpty(originalModelName)) {
                String aclMenu = "INSERT INTO `acl_menu` (id, menu_code, menu_name, menu_icon, menu_link, source_id, parent_id, is_system, is_leaf_node, menu_type, plat_type, ten_type, soft_version, status, remarks, application_id, create_user, create_time, update_user, update_time, delete_flag, bpid, mpid, menu_sort, func_code, source) " +
                        "VALUES ('" + code + "','','" + name + "','','stock/dashboard','1','610000',1, 0, 0, 0, 0, 0, 0, NULL, NULL,'choice','" + dateTime + "', NULL,'" + dateTime + "', 1, NULL, NULL, 0,'" + code + "', 1);" + "\r\n";
                String aclMenuGroup = "INSERT INTO `acl_menugroups` (id, tenant_id, menugroups_name, menugroups_type, parent_id, source_id, is_system, status, remarks, create_user, create_time, update_user, update_time, delete_flag) " +
                        "VALUES ('" + code + "','1','" + name + "', 0,'" + parentCode + "','1', 1, 1, NULL,'choice','2019-2-18 15:39:01','choice','" + dateTime + "', 1);" + "\r\n";
                String aclRelMenuGroup = "INSERT INTO `acl_rel_menugroups_menu` (id, menugroups_id, menu_id, tenant_id, create_user, create_time, update_user, update_time, delete_flag) " +
                        "VALUES ('610000_" + menuId + "','" + code + "','" + code + "','1','chensen','" + dateTime + "','chensen','" + dateTime + "', 1);" + "\r\n";
                String basAppEdition = "INSERT INTO `bas_app_edition_menugroup`(`id`, `menugroup_id`, `edition_id`, `menu_type`, `status`, `delete_flag`, `create_time`, `create_user`, `update_time`, `update_user`) " +
                        "VALUES('" + menuId + "','" + code + "','gyl2','0','1','1','" + dateTime + "','choice','" + dateTime + "','choice');" + "\r\n";
                os.write(aclMenu.getBytes());
                os.write(aclMenuGroup.getBytes());
                os.write(aclRelMenuGroup.getBytes());
                os.write(basAppEdition.getBytes());
                return;
            }
            if (!StringUtils.isEmpty(originalCode)) {
                commonSql(os, originalCode);
                return;
            }
            if (!StringUtils.isEmpty(originalParentCode) && StringUtils.isEmpty(originalModelName)) {
                String update = "update `acl_menugroups` set parent_id='" + parentCode + "' where id='" + code + "';" + "\r\n";
                os.write(update.getBytes());
            }
            if (!StringUtils.isEmpty(originalParentCode) && !StringUtils.isEmpty(originalModelName)) {
                String update1 = "update `acl_menu` set menu_name='" + name + "' where id='" + code + "';" + "\r\n";
                String update2 = "update `acl_menugroups` set parent_id='" + parentCode + "', menugroups_name='"+name+"' where id='" + code + "';" + "\r\n";
                os.write(update1.getBytes());
                os.write(update2.getBytes());
            }
            if (!StringUtils.isEmpty(originalModelName)) {
                String update1 = "update `acl_menu` set menu_name='" + name + "' where id='" + code + "';" + "\r\n";
                String update2 = "update `acl_menugroups` set menugroups_name='" + name + "' where id='" + code + "';" + "\r\n";
                os.write(update1.getBytes());
                os.write(update2.getBytes());
            }
        }
    }

    private void required(String code, String parentCode, String name) {
        if (StringUtils.isEmpty(code)){
            throw new RuntimeException("编码不能为空");
        }
        if (StringUtils.isEmpty(parentCode)){
            throw new RuntimeException("父编码不能为空");
        }
        if (StringUtils.isEmpty(name)){
            throw new RuntimeException("模块名称不能为空");
        }
    }

    private void commonSql(FileOutputStream os, String originalCode) throws IOException {
        String delete1 = "delete from `acl_menu` where id='" + originalCode + "';" + "\r\n";
        String delete2 = "delete from `acl_menugroups` where id='" + originalCode + "';" + "\r\n";
        String delete3 = "delete from `acl_rel_menugroups_menu` where menu_id='" + originalCode + "';" + "\r\n";
        String delete4 = "delete from `bas_app_edition_menugroup` where menugroup_id='" + originalCode + "';" + "\r\n";
        os.write(delete1.getBytes());
        os.write(delete2.getBytes());
        os.write(delete3.getBytes());
        os.write(delete4.getBytes());
    }

    public void download(HttpServletResponse response) throws IOException {
        String fileName = "权限编码模板.xlsx";
        InputStream inputStream = FileUtil.getFileInputStream(fileName);
        downloadFile(response, fileName,inputStream);
    }


    public void openFile(HttpServletResponse response) throws IOException {
        String name = AuthExeService.fileName;
        String path = AuthExeService.filePath;
        downloadFile(response, name, new FileInputStream(path));

    }

    private void downloadFile(HttpServletResponse response, String fileName, InputStream inputStream) throws IOException {
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

        ServletOutputStream outputStream = response.getOutputStream();
        int read;
        int buffer = 1024;
        byte[] data = new byte[buffer];
        while ((read = inputStream.read(data)) != -1) {
            outputStream.write(data, 0, read);
        }
        inputStream.close();
        outputStream.flush();
        outputStream.close();
    }

    public void export(HttpServletResponse response) throws Exception {
        List<OrderTemplateDetail> list = new ArrayList<>();
        OrderTemplateDetail entity;
        for (int i = 0; i < 1500; i++) {
            entity = new OrderTemplateDetail();
            entity.setIndex(i+1+"");
            entity.setGoodsCode("goods"+i);
            entity.setGoodsName("物品"+i);
            entity.setProcUnitName("千克");
            entity.setProcDualUnitName("斤");
            entity.setTaxPrice(new BigDecimal(String.valueOf((i*(Math.random()*10)+1))));
            entity.setOrderNum(new BigDecimal(String.valueOf(i*(Math.random()*100)+1)));
            entity.setOrderDualNum(new BigDecimal(String.valueOf(i*(Math.random()*10)+1)));
//            BigDecimal taxAmount = new BigDecimal(entity.getTaxPrice().toString()).multiply(new BigDecimal(entity.getOrderNum().toString())).setScale(2, RoundingMode.HALF_UP);
//            entity.setTaxAmount(taxAmount);
//            BigDecimal noTaxAmount = new BigDecimal(entity.getTaxAmount().toString()).divide(new BigDecimal(1.1),RoundingMode.HALF_UP).setScale(2,RoundingMode.HALF_UP);
//            entity.setNoTaxAmount(noTaxAmount);
            if (i%2==0){
                entity.setRemark("备注"+i);
            }
            list.add(entity);

        }
//        OrderTemplateExportEntity exportEntity = new OrderTemplateExportEntity();
//        exportEntity.setBillNo("CG11906017000003");
//        exportEntity.setCustomerName("辰森测试店");
//        exportEntity.setOrderDate(new Date());
//        exportEntity.setArriveDate(new Date());
//        exportEntity.setStatus("发货中");
//        exportEntity.setOrderOrgName("压力门店");
//        exportEntity.setAcceptanceOrgName("亚利门店");
//        exportEntity.setMark("啦啦啦");
//        exportEntity.setList(list);

//        ExcelTemplateExportEntity templateEntity = new ExcelTemplateExportEntity();
//        templateEntity.setData(exportEntity);
//        templateEntity.setHeadingStartRow(5);
//        templateEntity.setTemplateName("订单");
//        templateEntity.setExportTemplateName("辰森体验店_订单["+exportEntity.getBillNo()+"].xls");
//        templateEntity.setResponse(response);
//        ExcelUtils.templateExport(templateEntity);

//        ExcelExportEntity excelExportEntity = new ExcelExportEntity();
//        excelExportEntity.setData(list);
//        excelExportEntity.setPojoClass(OrderTemplateDetail.class);
//        excelExportEntity.setExportTemplateName("订单");
//        excelExportEntity.setSheetName("订单");
//        excelExportEntity.setResponse(response);
//        ExcelUtils.export(excelExportEntity);
    }
}
